(in-package :easy-zeromq-tests)

(defclass %test-encoding-class ()
  ((a :initarg :a :initform nil :accessor a)
   (b :initarg :b :initform nil :accessor b)))

(defstruct (%test-encoding-struct (:constructor make-test-encoding-struct (&key a b)))
  a b)

(defclass %test-undefenoding () ; this class will not defencoding intentionally
  ((a :initarg :a :initform nil :accessor a)
   (b :initarg :b :initform nil :accessor b)))

(define-test defencoding :parent encoding
  (finish (easy-zeromq::defencoding %test-encoding-class a b))
  (finish (easy-zeromq::defencoding %test-encoding-struct a b)))

(define-test encode/decode :parent encoding
  (let ((int 10000)
        (str "abcd")
        (sym 'abcd)
        (kwd :abcd)
        (vec #(1 2 3))
        (lst (list 'a 1 :b "asd" #(1 2 3)))
        (class (make-instance '%test-encoding-class :a 1 :b "abc"))
        (struct (make-test-encoding-struct :a 1 :b "abc")))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::encode int))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::encode str))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::encode sym))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::encode kwd))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::encode vec))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::encode lst))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::encode class))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::encode struct))
    (is =      int (easy-zeromq::decode (easy-zeromq::encode int)))
    (is equal  str (easy-zeromq::decode (easy-zeromq::encode str)))
    (is eq     sym (easy-zeromq::decode (easy-zeromq::encode sym)))
    (is eq     kwd (easy-zeromq::decode (easy-zeromq::encode kwd)))
    (is equalp vec (easy-zeromq::decode (easy-zeromq::encode vec)))
    (is equalp lst (easy-zeromq::decode (easy-zeromq::encode lst)))
    (of-type %test-encoding-class  (easy-zeromq::decode (easy-zeromq::encode class)))
    (of-type %test-encoding-struct (easy-zeromq::decode (easy-zeromq::encode struct)))))

(define-test handler-encode/decode :parent encoding
  (let ((int 10000)
        (str "abcd")
        (sym 'abcd)
        (kwd :abcd)
        (vec #(1 2 3))
        (lst (list 'a 1 :b "asd" #(1 2 3)))
        (class (make-instance '%test-encoding-class :a 1 :b "abc"))
        (struct (make-test-encoding-struct :a 1 :b "abc"))
        (undef-class (make-instance '%test-undefenoding :a 1 :b "abc"))
        (indecodable #(1 2 3)))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::handler-encode int))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::handler-encode str))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::handler-encode sym))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::handler-encode kwd))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::handler-encode vec))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::handler-encode lst))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::handler-encode class))
    (of-type (simple-array (unsigned-byte 8) (*)) (easy-zeromq::handler-encode struct))
    (is eql nil (easy-zeromq::handler-encode undef-class))
    (is =      int (easy-zeromq::handler-decode (easy-zeromq::handler-encode int)))
    (is equal  str (easy-zeromq::handler-decode (easy-zeromq::handler-encode str)))
    (is eq     sym (easy-zeromq::handler-decode (easy-zeromq::handler-encode sym)))
    (is eq     kwd (easy-zeromq::handler-decode (easy-zeromq::handler-encode kwd)))
    (is equalp vec (easy-zeromq::handler-decode (easy-zeromq::handler-encode vec)))
    (is equalp lst (easy-zeromq::handler-decode (easy-zeromq::handler-encode lst)))
    (of-type %test-encoding-class  (easy-zeromq::handler-decode (easy-zeromq::handler-encode class)))
    (of-type %test-encoding-struct (easy-zeromq::handler-decode (easy-zeromq::handler-encode struct)))
    (is eql nil (easy-zeromq::handler-decode indecodable))))
